package org.bwf.study.servcie.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.bwf.obj.bo.FilmQueryListBO;
import org.bwf.obj.dto.FilmQueryListDTO;
import org.bwf.obj.dto.FilmQueryModelDTO;
import org.bwf.study.aop.RedisAnnotation;
import org.bwf.study.model.*;
import org.bwf.study.servcie.FilmService;
import org.bwf.study.util.ElasticSearchClientUtil;
import org.bwf.study.util.JsonUtil;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Service("filmServiceEsImpl")
@Slf4j
public class FilmServiceEsImpl implements FilmService {

    @Resource
    private ElasticSearchClientUtil esUtil;

    @Override
    @RedisAnnotation(Duration = 700)
    public FilmQueryListDTO FilmQueryList(FilmQueryListBO filmQueryListBO) {

        FilmQueryListDTO filmQueryListDTO = new FilmQueryListDTO();

        // 加载全部的类别信息
        SearchHit[] cateHits = esUtil.boolQueryDocuments("category",50,0,null);
//        for(var cate : cateHits){
//            Category category = new Category();
//            // 通过类型中的构造函数进行获取新的实例，  反射
//            try {
//                BeanUtils.populate(category, cate.getSourceAsMap());
//                categoryList.add(category);
//            } catch (IllegalAccessException | InvocationTargetException e) {
//                e.printStackTrace();
//            }
//        }
        // 把类别集合加入dto
        filmQueryListDTO.setCategories(esUtil.toList(Category.class, cateHits));

        // 加载全部的区域信息
        SearchHit[] regionHits = esUtil.boolQueryDocuments("region",50,0,null);
//        List<FilmRegion> filmRegionList = new ArrayList<>();
//        for(var region : regionHits){
//            FilmRegion filmRegion = new FilmRegion();
//            try {
//                BeanUtils.populate(filmRegion, region.getSourceAsMap());
//                filmRegionList.add(filmRegion);
//            } catch (IllegalAccessException | InvocationTargetException e) {
//                e.printStackTrace();
//            }
//        }
        // 把区域集合加入dto
        filmQueryListDTO.setRegions(esUtil.toList(FilmRegion.class, regionHits));

        // 处理BO中的参数
        // 创建一个累加条件的查询对象
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        if(filmQueryListBO.getCateId() != null)
            boolQueryBuilder.filter(QueryBuilders.termQuery("filmCateQuery", filmQueryListBO.getCateId()));
        if(filmQueryListBO.getRegionId() != null)
            boolQueryBuilder.filter(QueryBuilders.termQuery("filmRegionQuery", filmQueryListBO.getRegionId()));
        if(filmQueryListBO.getYears() != null && !"".equals(filmQueryListBO.getYears()))
            boolQueryBuilder.filter(QueryBuilders.termQuery("filmYears", filmQueryListBO.getYears()));

        // 1 1-1 = 0 * 10  从0   10
        // 2 2-1 = 1 * 10  从10    10
        // 计算from， 也就是数据从什么地方开始取
        int from = (filmQueryListBO.getCurrentIndex()-1) * filmQueryListBO.getPageSize();
        // 计算总记录数
        long totalRecord = esUtil.boolQueryDocumentCount("film",boolQueryBuilder);
        // 计算总页数
        int totalPage =(int) (totalRecord % filmQueryListBO.getPageSize() == 0 ?
                totalRecord / filmQueryListBO.getPageSize() : totalRecord / filmQueryListBO.getPageSize() + 1);

        SearchHit[] filmHits = esUtil.boolQueryDocuments("film", filmQueryListBO.getPageSize(),from,boolQueryBuilder);
//        List<Film> filmList = new ArrayList<>();
//        for(var f : filmHits){
//            Film film = new Film();
//            try {
//                BeanUtils.populate(film, f.getSourceAsMap());
//                filmList.add(film);
//            } catch (IllegalAccessException | InvocationTargetException e) {
//                e.printStackTrace();
//            }
//        }

        filmQueryListBO.setTotalRecord(totalRecord);
        filmQueryListBO.setTotalPage(totalPage);

        filmQueryListDTO.setFilms(esUtil.toList(Film.class, filmHits));
        filmQueryListDTO.setBo(filmQueryListBO);



        return filmQueryListDTO;
    }

    @Override
    @RedisAnnotation(Duration = 900)
    public FilmQueryModelDTO FilmQueryModel(Integer filmId) {

        FilmQueryModelDTO filmQueryModelDTO = new FilmQueryModelDTO();
        SearchHit[] filmHits = esUtil.MatchPhraseQueryDocument("film","filmId",filmId.toString(),1,0);
        if(filmHits.length <= 0 ) return null;

        Film film = esUtil.toObj(Film.class,filmHits[0]);

        // 处理film电影中的json字符串
        filmQueryModelDTO.setActors(JsonUtil.decodeJsonToList(film.getFilmActors(), FilmActor.class));
        filmQueryModelDTO.setAwards(JsonUtil.decodeJsonToList(film.getFilmAwards(), FilmAwards.class));
        filmQueryModelDTO.setAdvances(JsonUtil.decodeJsonToList(film.getFilmAdvance(), FilmAdvance.class));
        filmQueryModelDTO.setAttributes(JsonUtil.decodeJsonToList(film.getFilmAttribute(), FilmAttribute.class));
        filmQueryModelDTO.setImages(JsonUtil.decodeJsonToList(film.getFilmImgs(), FilmImg.class));
        filmQueryModelDTO.setFilm(film);
        // 处理评论
        SearchHit[] commentHits = esUtil.MatchPhraseQueryDocument("comment","filmId",filmId.toString(),10,0);
        filmQueryModelDTO.setComments(esUtil.toList(Comment.class, commentHits));


        return filmQueryModelDTO;
    }
}
